/*
 * mempack - Memory data pack and unpack library
 * author	: calvin
 * email	: calvinwilliams@163.com
 *
 * Licensed under the LGPL v2.1, see the file LICENSE in base directory.
 */

#include "mempack.h"

ssize_t MemPack_uint8_to_1byte( uint8_t i , struct AppendBuffer *buf )
{
	ssize_t	len ;
	char	*c = (char*) & i ;
	char	**fill_ptr_ptr = NULL ;
	
	len = TryOffsetAppendBufferFillPtr( buf , 1 ) ;
	if( len < 0 )
		return -1;
	
	fill_ptr_ptr = GetAppendBufferFillPtrPtr( buf ) ;
	
	*((*fill_ptr_ptr)++) = (*c) ;
	*(*fill_ptr_ptr) = '\0' ;
	
	return 1;
}

ssize_t MemPack_uint16_to_2byte( uint16_t i , struct AppendBuffer *buf )
{
	ssize_t	len ;
	char	*c = (char*) & i ;
	char	**fill_ptr_ptr = NULL ;
	
	len = TryOffsetAppendBufferFillPtr( buf , 2 ) ;
	if( len < 0 )
		return -1;
	
	fill_ptr_ptr = GetAppendBufferFillPtrPtr( buf ) ;
	
	i = htons(i) ;
	
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*(*fill_ptr_ptr) = '\0' ;
	
	return 2;
}

ssize_t MemPack_uint32_to_4byte( uint32_t i , struct AppendBuffer *buf )
{
	i = htonl(i) ;
	
	return MemPack_uint32_to_4byte_nobyteorder( i , buf );
}

ssize_t MemPack_uint32_to_4byte_nobyteorder( uint32_t i , struct AppendBuffer *buf )
{
	ssize_t	len ;
	char	*c = (char*) & i ;
	char	**fill_ptr_ptr = NULL ;
	
	len = TryOffsetAppendBufferFillPtr( buf , 4 ) ;
	if( len < 0 )
		return -1;
	
	fill_ptr_ptr = GetAppendBufferFillPtrPtr( buf ) ;
	
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*(*fill_ptr_ptr) = '\0' ;
	
	return 4;
}

ssize_t MemPack_uint64_to_8byte( uint64_t i , struct AppendBuffer *buf )
{
	ssize_t	len ;
	char	*c = (char*) & i ;
	char	**fill_ptr_ptr = NULL ;
	
	len = TryOffsetAppendBufferFillPtr( buf , 8 ) ;
	if( len < 0 )
		return -1;
	
	fill_ptr_ptr = GetAppendBufferFillPtrPtr( buf ) ;
	
	i = hton64(i) ;
	
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*((*fill_ptr_ptr)++) = (*c++) ;
	*(*fill_ptr_ptr) = '\0' ;
	
	return 8;
}

ssize_t MemPack_charpt_to_nbyte( char *p , size_t n , struct AppendBuffer *buf )
{
	return AppendBufferMemoryBytes( buf , p , n );
}

ssize_t MemUnpack_1byte_to_uint8( struct AppendBuffer *buf , uint8_t *i )
{
	char	*fill_ptr = GetAppendBufferFillPtr(buf) ;
	char	**parse_ptr_ptr = GetAppendBufferParsePtrPtr(buf) ;
	
	if( fill_ptr - (*parse_ptr_ptr) < 1 )
		return -1;
	
	(*i) = *(uint8_t*)(*parse_ptr_ptr) ;
	(*parse_ptr_ptr)++;
	
	return 1;
}

ssize_t MemUnpack_2byte_to_uint16( struct AppendBuffer *buf , uint16_t *i )
{
	char	*fill_ptr = GetAppendBufferFillPtr(buf) ;
	char	**parse_ptr_ptr = GetAppendBufferParsePtrPtr(buf) ;
	
	if( fill_ptr - (*parse_ptr_ptr) < 2 )
		return -1;
	
	(*i) = *(uint16_t*)(*parse_ptr_ptr) ;
	(*i) = ntohs(*i) ;
	(*parse_ptr_ptr) += 2 ;
	
	return 2;
}

ssize_t MemUnpack_4byte_to_uint32( struct AppendBuffer *buf , uint32_t *i )
{
	ssize_t		len ;
	
	len = MemUnpack_4byte_to_uint32_nobyteorder( buf , i ) ;
	if( len != 4 )
		return -1;
	
	(*i) = ntohl(*i) ;
	
	return len;
}

ssize_t MemUnpack_8byte_to_uint64( struct AppendBuffer *buf , uint64_t *i )
{
	char	*fill_ptr = GetAppendBufferFillPtr(buf) ;
	char	**parse_ptr_ptr = GetAppendBufferParsePtrPtr(buf) ;
	
	if( fill_ptr - (*parse_ptr_ptr) < 8 )
		return -1;
	
	(*i) = *(uint64_t*)(*parse_ptr_ptr) ;
	(*i) = ntoh64(*i) ;
	(*parse_ptr_ptr) += 8 ;
	
	return 8;
}

ssize_t MemUnpack_4byte_to_uint32_nobyteorder( struct AppendBuffer *buf , uint32_t *i )
{
	char	*fill_ptr = GetAppendBufferFillPtr(buf) ;
	char	**parse_ptr_ptr = GetAppendBufferParsePtrPtr(buf) ;
	
	if( fill_ptr - (*parse_ptr_ptr) < 4 )
		return -1;
	
	(*i) = *(uint32_t*)(*parse_ptr_ptr) ;
	(*parse_ptr_ptr) += 4 ;
	
	return 4;
}

ssize_t MemUnpack_nbyte_to_charpt( struct AppendBuffer *buf , size_t n , char **p )
{
	char	*fill_ptr = GetAppendBufferFillPtr(buf) ;
	char	**parse_ptr_ptr = GetAppendBufferParsePtrPtr(buf) ;
	
	if( fill_ptr - (*parse_ptr_ptr) < n )
		return -1;
	
	(*p) = (*parse_ptr_ptr) ;
	(*parse_ptr_ptr)+=n;
	
	return n;
}

